package com.yfp.operation.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yfp.common.core.utils.StringUtils;
import com.yfp.operation.domain.OrderListDO;
import com.yfp.operation.domain.PositionSharing;
import com.yfp.operation.domain.UserBill;
import com.yfp.operation.domain.dto.SubAccountDTO;
import com.yfp.operation.domain.vo.SharingVO;
import com.yfp.operation.domain.vo.SubAccountVO;
import com.yfp.operation.mapper.MachineMapper;
import com.yfp.operation.mapper.OrderListMapper;
import com.yfp.operation.mapper.PositionSharingMapper;
import com.yfp.operation.service.AccountService;
import com.yfp.operation.service.PositionSharingService;
import com.yfp.operation.service.UserBillService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 
 * @version 1.0
 * @date 2024-06-11 15:53
 */
@Service
@Slf4j
public class AccountServiceImpl implements AccountService {

    @Resource
    private MachineMapper machineMapper;
    @Resource
    private UserBillService userBillService;
    @Resource
    private PositionSharingMapper positionSharingMapper;
    @Resource
    private PositionSharingService positionSharingService;
    @Resource
    private OrderListMapper orderListMapper;

    /**
     * 多条件查询设备分账详情列表
     *
     * @param subAccountDTO
     * @return
     */
    @Override
    public List<SubAccountVO> subAccount(List<String> machineIdList, SubAccountDTO subAccountDTO) {
        log.info("多条件查询设备分账详情列表,入参:{}", machineIdList);
        if (machineIdList == null || machineIdList.size() <= 0) {
            return new ArrayList<>();
        }
        subAccountDTO.setMachineIdList(machineIdList);
        // 根据设备id获取订单分账列表
        List<UserBill> list = userBillService.selectMachineSharing(subAccountDTO);
        if (list.isEmpty()) {
            return new ArrayList<>();
        }

        // 将订单分账列表的数据以设备id为维度，将数据累加，得到设备分账数据
        HashMap<String, SubAccountVO> hashMap = new HashMap<>();
        for (UserBill userBill : list) {
            String machineId = userBill.getMachineId();
            if (hashMap.containsKey(machineId)) {
                SubAccountVO subAccountVO = hashMap.get(machineId);
                Double sumMoney = subAccountVO.getSumMoney();
                Double subMoney = subAccountVO.getSubMoney();
                Double freezeMoney = subAccountVO.getFreezeMoney();
                Double canWithdrawMoney = subAccountVO.getCanWithdrawMoney();
                Double alreadyWithdrawMoney = subAccountVO.getAlreadyWithdrawMoney();

                BigDecimal payMoney = userBill.getPayMoney();
                BigDecimal money = userBill.getMoney();
                Double allFreezeMoney = userBill.getAllFreezeMoney();
                Double canWithdrawMoney1 = userBill.getCanWithdrawMoney();
                Double alreadyWithdrawMoney1 = userBill.getAlreadyWithdrawMoney();
                subAccountVO.setSumMoney(new BigDecimal(sumMoney).add(payMoney).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                subAccountVO.setSubMoney(new BigDecimal(subMoney).add(money).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                subAccountVO.setFreezeMoney(new BigDecimal(freezeMoney).add(new BigDecimal(allFreezeMoney)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                subAccountVO.setCanWithdrawMoney(new BigDecimal(canWithdrawMoney).add(new BigDecimal(canWithdrawMoney1)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                subAccountVO.setAlreadyWithdrawMoney(new BigDecimal(alreadyWithdrawMoney).add(new BigDecimal(alreadyWithdrawMoney1)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                subAccountVO.setGiftGold(userBill.getGiftGold().add(subAccountVO.getGiftGold()));
            } else {
                SubAccountVO subAccountVO = new SubAccountVO();
                subAccountVO.setMachineId(machineId);
                subAccountVO.setFeeRate(userBill.getFeeRate());
                subAccountVO.setProportion(userBill.getProportion());
                subAccountVO.setSumMoney(userBill.getPayMoney().doubleValue());
                subAccountVO.setSubMoney(userBill.getMoney().doubleValue());
                subAccountVO.setFreezeMoney(userBill.getAllFreezeMoney());
                subAccountVO.setCanWithdrawMoney(userBill.getCanWithdrawMoney());
                subAccountVO.setAlreadyWithdrawMoney(userBill.getAlreadyWithdrawMoney());
                subAccountVO.setPositionId(userBill.getPositionId());
                subAccountVO.setGiftGold(userBill.getGiftGold());
                hashMap.put(machineId, subAccountVO);
            }
        }

        List<SubAccountVO> subAccountVOS = new ArrayList<>(hashMap.values());

        // 获取设备id列表
        List<String> machineIds = subAccountVOS.stream().map(SubAccountVO::getMachineId).collect(Collectors.toList());
        // 根据设备id获取点位信息
        List<PositionSharing> positionSharings = positionSharingService.selectList(machineIds);

        for (SubAccountVO subAccountVO : subAccountVOS) {
            List<PositionSharing> sharingList = positionSharings.stream().filter(positionSharing -> positionSharing.getMachineId().equals(subAccountVO.getMachineId())).collect(Collectors.toList());
            subAccountVO.setPositionSharingList(sharingList);
        }

        ArrayList<SubAccountVO> subAccountVOList = new ArrayList<>();

        // 筛选条件是否有收款方账号，如果没有则直接返回数据
        if (!StrUtil.isBlank(subAccountDTO.getAccountNumber())) {
            // 根据创客账号查询点位信息
            List<String> positionIds = positionSharingMapper.getPositionSharing(subAccountDTO.getAccountNumber());
            for (SubAccountVO subAccountVO : subAccountVOS) {
                // 如果包含点位点位id，则返回
                if (positionIds.contains(subAccountVO.getPositionId())) {
                    subAccountVOList.add(subAccountVO);
                }
            }
            return subAccountVOList;
        } else {
            return subAccountVOS;
        }
    }

    /**
     * 根据点位id查询创客列表
     *
     * @param positionId
     * @return
     */
    @Override
    public List<PositionSharing> detail(String positionId) {
        if (positionId.isEmpty()) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<PositionSharing> wrapper = new LambdaQueryWrapper<PositionSharing>().eq(PositionSharing::getPositionId, positionId);
        List<PositionSharing> list = positionSharingMapper.selectList(wrapper);
        return list;
    }

    /**
     * 查询订单分账详情列表
     *
     * @param subAccountDTO
     * @return
     */
    @Override
    public List<UserBill> selectAllUserBill(SubAccountDTO subAccountDTO) {
        log.info("多条件查询订单分账详情列表,入参:{}", subAccountDTO);
        List<UserBill> list = null;
        if (StrUtil.isBlank(subAccountDTO.getMachineId())) {
            list = userBillService.selectAllUserBill(subAccountDTO);
        } else {
            list = userBillService.selectByMachineIdUserBill(subAccountDTO);
        }
        return list;
    }


    public List<UserBill> supplement(List<UserBill> list, String accountNumber) {
        if (list.isEmpty()) {
            return new ArrayList<>();
        }

//        Map<String, UserBill> userBillMap = list.stream().collect(Collectors.toMap(UserBill::getOrderSn, Function.identity()));
        List<String> orderSnList = list.stream().map(userBill -> userBill.getOrderSn()).collect(Collectors.toList());
        // 获取订单支付时间
        List<OrderListDO> orderListDOList = orderListMapper.getPayTime(orderSnList);
        Map<String, OrderListDO> orderListDOMap = orderListDOList.stream().collect(Collectors.toMap(OrderListDO::getOrderSn, Function.identity()));


        List<String> positionIds = new ArrayList<>();
        if (!StrUtil.isBlank(accountNumber)) {
            // 根据创客账号查询点位信息
            positionIds = positionSharingMapper.getPositionSharing(accountNumber);
        }

//        List<String> machineIds = list.stream().map(userBill -> userBill.getMachineId()).collect(Collectors.toList());
        Set<String> OrderIds = list.stream().map(userBill -> userBill.getOrderSn()).collect(Collectors.toSet());

        // 根据订单id获取分账人列表
        List<PositionSharing> positionSharingList = userBillService.getSharing(OrderIds);


        for (UserBill userBill : list) {
            String orderSn = userBill.getOrderSn();
            List<PositionSharing> sharingList = positionSharingList.stream().filter(positionSharing -> positionSharing.getOrderSn().equals(orderSn)).collect(Collectors.toList());
            // 支付时间
            if (orderListDOMap.containsKey(orderSn)) {
                OrderListDO orderListDO = orderListDOMap.get(orderSn);
                userBill.setPayTime(orderListDO.getPayTime());
            }
            // 分账接收方列表
            userBill.setPositionSharingList(sharingList);
        }

        // 筛选条件是否有收款方账号，如果没有则直接返回数据
        if (!StrUtil.isBlank(accountNumber)) {
            List<UserBill> userBills = new ArrayList<>();
            // 如果包含该点位id，则表示符合查询收款方账号的条件，需要将这条数据返回
            for (UserBill userBill : list) {
                if (positionIds.contains(userBill.getPositionId())) {
                    userBills.add(userBill);
                }
            }
            return userBills;
        } else {
            return list;
        }
    }

    /**
     * 创客分账统计列表
     *
     * @param userIds
     * @return
     */
    @Override
    public List<SharingVO> selectSharing(List<Integer> userIds) {

        List<SharingVO> list = userBillService.selectSharing(userIds);
        HashMap<String, SharingVO> map = new HashMap<>();

        for (SharingVO sharingVO : list) {
            // userid+type组成key，如果相同则数值累加
            String key = sharingVO.getType() + "-" + sharingVO.getUserId();
            if (map.containsKey(key)) {
                SharingVO vo = map.get(key);
                Double allPayMoney = sharingVO.getAllPayMoney();
                Double allMoney = sharingVO.getAllMoney();
                Double allFreezeMoney = sharingVO.getAllFreezeMoney();
                Double canWithdrawMoney = sharingVO.getCanWithdrawMoney();
                Double alreadyWithdrawMoney = sharingVO.getAlreadyWithdrawMoney();
                Double voAllPayMoney = vo.getAllPayMoney();
                Double voAllMoney = vo.getAllMoney();
                Double voAllFreezeMoney = vo.getAllFreezeMoney();
                Double voCanWithdrawMoney = vo.getCanWithdrawMoney();
                Double voAlreadyWithdrawMoney = vo.getAlreadyWithdrawMoney();
                vo.setAllPayMoney(new BigDecimal(allPayMoney).add(new BigDecimal(voAllPayMoney)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                vo.setAllMoney(new BigDecimal(allMoney).add(new BigDecimal(voAllMoney)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                vo.setAllFreezeMoney(new BigDecimal(allFreezeMoney).add(new BigDecimal(voAllFreezeMoney)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                vo.setCanWithdrawMoney(new BigDecimal(canWithdrawMoney).add(new BigDecimal(voCanWithdrawMoney)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                vo.setAlreadyWithdrawMoney(new BigDecimal(alreadyWithdrawMoney).add(new BigDecimal(voAlreadyWithdrawMoney)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                vo.setGiftGold(vo.getGiftGold().add(sharingVO.getGiftGold()));
            } else {
                map.put(key, sharingVO);
            }
        }

        List<SharingVO> sharingVOS = new ArrayList<>(map.values());
        return sharingVOS;
    }


}
